import {
  Body,
  Controller,
  Get,
  HttpException,
  HttpStatus,
  Param,
  Post,
  UseGuards,
} from '@nestjs/common';
import {
  ApiBasicAuth,
  ApiBearerAuth,
  ApiHeader,
  ApiOperation,
  ApiParam,
  ApiResponse,
  ApiTags,
} from '@nestjs/swagger';
import { CurrentUser } from 'src/decorators/current.user';
import { UserEntity } from 'src/types/modules/user/entities/user.entity';
import { syncValidate, unallow } from 'src/utils/validate';
import { Model } from 'mongoose';
import { InjectModel } from '@nestjs/mongoose';
import { JwtAuthGuard } from 'src/modules/user/jwt/jwt-auth.guard';
import { ITypeEntity } from '../types/type/superType.type';
import {
  ApiTypePutDto,
  ApiTypeGetReqDto,
  ApiTypeGetResDto,
} from '../types/dto/type.dto';
import { CurrentRole } from '@/decorators/current.role';
import { ClientRole } from '@/modules/user/role/role.type';
import { TypeService } from './type.service';
import { DataSourceService } from './dataSource.service';
import {
  ApiTypeImportFromOpenApiReqDto,
  ApiTypeSubmitImportTypesReqDto,
} from '../types/dto/openapi.dto';

@ApiTags('类型')
@ApiBearerAuth()
@Controller('type')
export class TypeController {
  constructor(
    private typeService: TypeService,
    private dataSourceService: DataSourceService,
    @InjectModel('type') private typeModel: Model<ITypeEntity>,
  ) {}

  @ApiOperation({ summary: '新增或更新类型' })
  @UseGuards(JwtAuthGuard)
  @Post('put')
  async put(
    @Body() params: ApiTypePutDto,
    @CurrentUser() user: UserEntity,
    @CurrentRole() role: ClientRole,
  ) {
    try {
      await syncValidate(params, {
        name: {
          required: true,
          enable: (values) => !['api', 'api-import'].includes(values.type),
        },
        desc: {
          required: true,
          enable: (values) =>
            !['api', 'vo', 'agent', 'cloud_function'].includes(values.type),
        },
        fields: {
          type: 'array',
          required: false,
        },
      });
    } catch (e) {
      throw new HttpException(e.message, HttpStatus.BAD_REQUEST);
    }
    const data = unallow(params, ['create_time', 'update_time', 'userId']);
    if (data.fields?.length > 0) {
      data.fields = data.fields.map((item: any) => {
        return unallow(item, ['apiImportEntity', 'importEntity']);
      });
    }
    if (typeof params._id !== 'undefined' && !params._id) {
      delete params._id;
      delete data._id;
    }

    // 使用新的 saveType 方法，包含所有业务逻辑
    return this.typeService.saveType(
      {
        _id: params._id,
        ...data,
      },
      {
        userId: user.id,
        teamId: role.teamId,
        skipValidation: false,
        skipPermissionCheck: false,
        skipHashCalculation: false,
        existType: undefined, // 让 saveType 自己处理查找逻辑
      },
    );
  }

  @ApiOperation({ summary: '获取类型列表' })
  @UseGuards(JwtAuthGuard)
  @Post('get')
  async get(
    @CurrentUser() u: UserEntity,
    @CurrentRole() role: ClientRole,
    @Body() params: ApiTypeGetReqDto,
  ): Promise<ApiTypeGetResDto> {
    return this.typeService.getType(params, u.id, role.teamId);
  }

  @ApiOperation({ summary: '删除类型' })
  @UseGuards(JwtAuthGuard)
  @Post('delete')
  async delete(
    @Body()
    params: {
      id: string;
    },
    @CurrentUser() u: UserEntity,
  ) {
    try {
      await syncValidate(params, {
        id: {
          required: true,
        },
      });
    } catch (e) {
      throw new HttpException(e.message, HttpStatus.BAD_REQUEST);
    }
    return this.typeModel.deleteOne({
      _id: params.id,
    }) as any;
  }

  @ApiOperation({ summary: '从OpenAPI文档导入模型' })
  @UseGuards(JwtAuthGuard)
  @Post('importFromOpenAPI')
  async importFromOpenAPI(
    @CurrentUser() u: UserEntity,
    @CurrentRole() role: ClientRole,
    @Body() params: ApiTypeImportFromOpenApiReqDto,
  ) {
    return this.dataSourceService.importTypesFromOpenapi(
      params,
      u.id,
      role.teamId,
    );
  }

  @ApiOperation({ summary: '确认导入模型' })
  @UseGuards(JwtAuthGuard)
  @Post('submitImportTypes')
  async submitImportTypes(
    @CurrentUser() u: UserEntity,
    @CurrentRole() role: ClientRole,
    @Body() params: ApiTypeSubmitImportTypesReqDto,
  ) {
    const { isSync, types, removeTypes } = params;
    const allTypes = types;
    const updateTypes: ITypeEntity[] = [];
    const createTypes: ITypeEntity[] = [];
    for (let i = 0; i < allTypes.length; i++) {
      const { _id, ...data } = allTypes[i];
      console.log(
        'condition: ',
        data.unikey ? { unikey: data.unikey } : { _id },
      );
      console.log('data: ', data);
      let existType = await this.typeModel
        .findOne(data.unikey ? { unikey: data.unikey } : { _id })
        .select(['_id']);
      if (
        data.type === 'vo' &&
        typeof data.fields !== 'undefined' &&
        data.fields.length === 0
      ) {
        throw new HttpException('字段不能为空', HttpStatus.BAD_REQUEST);
      }
      console.log('existType: ', existType);
      // 特殊情况处理（因为目前UniKey改变不一导致错误重复）
      if (data.unikey && !existType?._id) {
        const higherQuery = {
          type: data.type,
          projectId: data.projectId,
        };
        switch (data.type) {
          case 'vo':
            higherQuery['name'] = data.name;
            break;
          case 'api':
            higherQuery['uri'] = data.uri;
            higherQuery['method'] = data.method;
            break;
          case 'cloud_function':
            higherQuery['name'] = data.name;
          case 'action':
            higherQuery['name'] = data.name;
            break;
          case 'folder':
            higherQuery['folderPath'] = data.folderPath;
          case 'code':
            higherQuery['name'] = data.name;
            higherQuery['folderPath'] = data.folderPath;
            break;
          default:
            break;
        }
        console.log('higherQuery', higherQuery);
        existType = await this.typeModel.findOne(higherQuery).select(['_id']);
      }
      if (existType?._id) {
        data.update_time = isSync ? data.update_time || Date.now() : Date.now();
        console.log('data: ', data);
        await this.typeModel.updateOne({ _id: existType?._id }, data);
        updateTypes.push({
          _id: existType?._id,
          ...data,
        });
      } else {
        if (data.type === 'vo' && (!data.fields || data.fields.length === 0)) {
          throw new HttpException('字段不能为空', HttpStatus.BAD_REQUEST);
        }
        const type = new this.typeModel(allTypes[i]);
        const createdType = await type.save();
        createTypes.push(createdType);
      }
    }
    if (removeTypes?.length > 0) {
      await this.typeModel.deleteMany({ _id: { $in: removeTypes } });
    }
    return {
      updateTypes,
      createTypes,
      removeTypes,
    };
  }
}
